/*
 * Copyright 2007 Ulf Ochsenfahrt <ulf@ofahrt.de>
 *
 * This file is part of mnemoj, a software transactional memory implementation
 * that is based on Project Darkstar.
 *
 * mnemoj is free software: you can redistribute it
 * and/or modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation and
 * distributed hereunder to you.
 *
 * Project Darkstar Server is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.ofahrt.mnemoj.test;

import java.io.File;
import java.io.Serializable;

import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.DataManager;
import com.sun.sgs.app.Task;

import de.ofahrt.mnemoj.PersistenceManager;
import de.ofahrt.mnemoj.impl.SqlitePersistenceManager;

public class Main2
{

private final static String LOBBY = "lobby";

	private static class MyBootstrap implements Task, Serializable
	{
		private static final long serialVersionUID = 1L;
		@Override
		public void run()
		{
			DataManager manager = AppContext.getDataManager();
			manager.setBinding(LOBBY, new Lobby());
		}
	}
	
	private static class MyTask implements Task, Serializable
	{
		private static final long serialVersionUID = 1L;
		public MyTask()
		{/*OK*/}
		@Override
		public void run()
		{
			DataManager manager = AppContext.getDataManager();
			Lobby lobby = manager.getBinding(LOBBY, Lobby.class);
			lobby.setValue(lobby.getValue()+1);
		}
	}
	
	private static class FailedTask implements Task, Serializable
	{
		private static final long serialVersionUID = 1L;
		private final RuntimeException e = new RuntimeException("Failed!");
		public FailedTask()
		{/*OK*/}
		@Override
		public void run()
		{
			DataManager manager = AppContext.getDataManager();
			Lobby lobby = manager.getBinding(LOBBY, Lobby.class);
			lobby.setValue(-10000);
			throw e;
		}
	}
	
	private static class DebugTask implements Task, Serializable
	{
		private static final long serialVersionUID = 1L;
		public DebugTask()
		{/*OK*/}
		@Override
		public void run()
		{
			DataManager manager = AppContext.getDataManager();
			Lobby lobby = manager.getBinding(LOBBY, Lobby.class);
			System.out.println("Lobby = "+lobby.getValue());
		}
	}

public static void main(String[] args) throws InterruptedException
{
	final PersistenceManager manager = new SqlitePersistenceManager(new File("test.db"));
	manager.execute(new MyBootstrap());
	
	for (int i = 0; i < 10000; i++)
	{
		manager.execute(new MyTask());
		try
		{ manager.execute(new FailedTask()); }
		catch (RuntimeException e)
		{/*OK*/}
	}
	
	Thread[] threads = new Thread[4];
	threads[0] = new Thread(new Runnable()
		{
			public void run()
			{
				FailedTask task = new FailedTask();
				for (int j = 0; j < 1000000; j++)
				{
					try
					{ manager.execute(task); }
					catch (RuntimeException e)
					{/*OK*/}
				}
			}
		});
	for (int i = 1; i < threads.length; i++)
		threads[i] = new Thread(new Runnable()
			{
				public void run()
				{
					MyTask task = new MyTask();
					for (int j = 0; j < 1000000; j++)
					{
						manager.execute(task);
					}
				}
			});
	
	long start = System.currentTimeMillis();
	for (int i = 0; i < threads.length; i++)
		threads[i].start();
	for (int i = 0; i < threads.length; i++)
		threads[i].join();
	long stop = System.currentTimeMillis();
	System.out.println(stop-start);
	
	manager.execute(new DebugTask());
}

}
